Sed awk
De Wiki de Nelly & Richard.
Sommaire |
Expressions régulières
- Les expressions régulières sont utiles au quotidien dans l'utilisation de scripts, de programmation, egrep, ...
- Voici quelques outils qui vous aideront pour la réalisation de scripts.
Le caractère d'échappement \
- Le back-slash permet de désigner les caractères spécifiques suivant : . * ^ $ \ [ ]
exemple : $ echo 'c:\' | grep '\\' > nous renvoi bien c:\
Le point . et l'astérisque *
- Le point est aussi appelé caractère joker, il permet de remplacer n'importe quel caractère.
exemple : $ echo "test" | grep 't.st' > nous renvoi bien test
- L'astérisque lui va nous permettre de désigner 0, 1 ou plusieurs occurrences du caractère précédent
exemple : $ echo "ttttttt" | grep 't*' > nous renvoi bien ttttttt de même : $ echo "test" | grep 'tei*st' > nous renvoi bien test
L'accent circonflexe ^ et dollar $
- Ces deux caractères indique respectivement le début et la fin d'une ligne
exemple : $ echo "test" | grep '^test$' > nous renvoi bien test à l'inverse $ echo "test" | grep '^tes$' > ne renvoi rien
- Il peuvent rechercher une ligne vide : '^$'
Les crochets [ ] pour l'alternative
- Les crochets permettent de définir le ou logique
exemple : $ echo "test" | grep 't[ei]st' > renvoi test de même : $ echo "tist" | grep 't[ei]st' > renvoi tist ou : $ echo "teist" | grep 't[ei]*st' > renvoi teist
- Le tiret - permet de définir une plage (les chiffres de 2 à 7 -> [2-7])
exemple : $ echo "tEst" | grep 't[a-fA-F]st' > renvoi tEst
Les crochets [^ ] pour la négation
- Les crochets utilisés avec l'accent circonflexe permettent d'exprimer la négation
exemple : $ echo "test" | grep 't[^e]st' > ne renvoi rien
de même : $ echo "tist" | grep 't[^e]st' > renvoi tist
Les parenthèses \( \) pour les groupes
- Les parenthèses permettent d'isoler un groupe de caractères pour le rappeler éventuellement, l'exemple qui suit utilise sed nous verrons plus en détail les possibilité de cette commande plus bas.
exemple : $ echo "Quel beau paysage" | sed -e 's/^\(Quel beau\).*$/\1 tableau/' > renvoi : Quel beau tableau
Les éléments compris entre \( \) sont rappelés avec \1, \2 si il y a 2 sous ensemble, ...
Les accolades \{ \}
- Les accolades définissent le nombre d'occurrences du caractère, sous ensemble ou alternative qui les précèdent.
exemple :
$ echo "teeest" | grep 'te\{3\}st'
> renvoi : teeest
- Comme les parenthèses les accolades sont utilisées avec les back-slash \{ \}
sed
- Sed permet d'effectuer des manipulations simples sur des fichiers textes. Vous trouverez des informations dans la manpage de sed ou l'infopage de sed répondront à toutes vos questions.
- dans les exemples qui suivent j'utiliserais ce fichier sed.txt :
azerty AZERTY 01234 azErty0uiOp3qsdf6 a z e r t y a/z/e/r/t/y blabla bla bla bla
options
- -i : enregistre les modifications dans le fichier traité.
sed -i 'expression' fichier
- -e : permet d'appeler plusieurs commandes à la suite.
sed -e 'expression' -e 'expression' fichier
- -n : silencieux utilise avec p.
# même comportement qu'un cat sed -n 'p' fichier
- -f : utilisation d'un fichier script.
le format du fichier script est :
'expression' 'expression' ... # usage : sed -f file-script fichier
expressions
syntaxe
- De manière générale :
'<début_recherche>,<fin_recherche><commande>'
- <début_recherche> et <fin_recherche> peuvent-être des numéros de ligne ou bien des expressions régulière.
- plusieurs <commande> peuvent être placées.
sed -n '2,/[0-9]/p' sed.txt # recherchera à partir de la 2° ligne jusqu'au prochain caractère numérique # renvoie : AZERTY 01234
subtitution
Elle doit-être de loin la plus connue vous l'utilisez peut-être déjà avec vim
- syntaxe : 's/<expression régulière>/<chaîne de remplacement>/'
- exemple :
sed -n '2,/[0-9]/s/[0-9]/Number/p' sed.txt # renvoie : Number1234
- vous pouvez spécifier une sous-chaîne et la rappeler dans la chaîne de remplacement \n
- exemple :
sed -n '2s/\(AZ\)E/\1@/p' sed.txt # renvoie : AZ@RTY
suppression
divers
- g : répète la commande tant que le texte recherché est trouver.
- exemple :
sed -n 's/a/@/pg' sed.txt # renvoie : @zerty @zErty0uiOp3qsdf6 @ z e r t y @/z/e/r/t/y bl@bl@ bl@ bl@ bl@
- i : ignore la casse
- exemple :
sed -n 's/a/@/pgi' sed.txt @zerty @ZERTY @zErty0uiOp3qsdf6 @ z e r t y @/z/e/r/t/y bl@bl@ bl@ bl@ bl@
awk
- Awk est un langage qui permet également la manipulation de chaînes de caractères et/ou de fichiers texte. En l'utilisant de façon avancée vous obtiendrez la puissance d'un tableur.
- Ce qui suit est vraiment un survol des possibilités de g(awk), la manpage de awk ainsi que les liens en bas de page vous permettrons d'en savoir d'avantage.
- pour les exemples qui vont suivre nous utiliserons le fichier généré aléatoirement : awk_wiki.csv
options courantes
- -F : désigne le séparateur de champs, par défaut il s'agit de l'espace
$ echo 'toto,titi' | awk -F ',' '{print $2}'
titi
pour rappel : \\ \ \" " \a alert, ascii 7 \b backspace, ascii 8 \t tab, ascii 9 \n newline, ascii 10 \v vertical tab, ascii 11 \f formfeed, ascii 12 \r carriage return, ascii 13
- -f : permet de faire appel à un fichier texte contenant le script
# test.awk :
{
print $2
}
$ echo 'toto,titi' | awk -F ',' -f test.awk titi
- -v : indique une variable venant de l'extérieure
$ echo 'toto,titi' | awk -F ',' -v maVar="teste les variables" '{print $2 " " maVar}'
titi teste les variables
utilisations
syntaxe générale
- De manière générale awk exécute pour chaque ligne les instructions contenu dans chaque bloc si les lignes et/ou éléments correspondent aux conditions, expressions, ... définis :
conditions et/ou regexp
{
instructions1
instructions2
...
}
...
- les blocs BEGIN et END
Ces deux blocs sont particuliers, ils permettent le traitement d'instructions avant et après l'exécution des blocs standards.
# exemples avec le fichier awk_wiki.csv
BEGIN {
ligne=0
}
# match le champ 4 commençant par un G
$4 ~ /^G/ {
ligne+=1
}
END {
print "match : " ligne " ligne(s)"
}
# résultat :
# match : 45 ligne(s)
exemples
Étant donné que le man 1 mawk contient tout ce dont vous avez besoin pour utiliser awk je vous laisse la consulter en parcourant ces exemples, j'essaierais tout de même de les commenter.
- Modification de notre fichier awk_wiki.csv
# ajout de la taille du champs 3 et 4 en début de ligne
$ awk -F ',' '{result=length($3) "," length($4) "," $0; print result ; ligne++}' awk_wiki.csv > test2.csv
- Bon on se fait un peu chier là :(
nombre d'occurences
# exemple fichier test2.awk
# initialisation des variables
BEGIN {
FS=","
ligne=0
}
# match des champ1 présent plus d'une fois dans le fichier
!list[$1]++ {
ligne++
}
# pour toutes les lignes on compte le nombre d'occurrences des éléments de list
# on stock le tout dans list2
{
for (i in list) {
if (i == $1)
list2[i]+=1
}
}
# affichage des résultats
END {
for (i in list)
print "$1 contient " list2[i] " fois la valeur " i
print "------------------\n" ligne " valeurs uniques"
}
# resultat : awk -f test2.awk test2.csv
# $1 contient 129 fois la valeur 10
# $1 contient 113 fois la valeur 11
# $1 contient 1 fois la valeur 3
# $1 contient 120 fois la valeur 4
# $1 contient 120 fois la valeur 5
# $1 contient 142 fois la valeur 6
# $1 contient 129 fois la valeur 7
# $1 contient 109 fois la valeur 8
# $1 contient 138 fois la valeur 9
# ------------------
# 9 valeurs uniques
- nombre d'occurences
On utilisera un fichier sous ce format :
data1 data2 data3 c1 c2 c3 c4 c5 e1 e2 1 < c < 50 et 1 < e < 9
{
# on rempli les listes
c1[NR]=$4
c2[NR]=$5
c3[NR]=$6
c4[NR]=$7
c5[NR]=$8
e1[NR]=$9
e2[NR]=$10
}
END {
# on compte le nombre de 1, de 2, ... par liste
i=0
while (i < 50) {
i++
for (c in c1) {
if (c1[c] == i) {
liste1[i] = liste1[i]+1
}
if (c2[c] == i) {
liste2[i] = liste2[i]+1
}
if (c3[c] == i) {
liste3[i] = liste3[i]+1
}
if (c4[c] == i) {
liste4[i] = liste4[i]+1
}
if (c5[c] == i) {
liste5[i] = liste5[i]+1
}
if (e1[c] == i) {
liste6[i] = liste6[i]+1
}
if (e2[c] == i) {
liste7[i] = liste7[i]+1
}
}
}
# impression du résultat
i = 0
while (i < 50) {
i++
print i "\t: " liste1[i] "\t" liste2[i] "\t" liste3[i] "\t" liste4[i] "\t" liste5[i] "\t" liste6[i] "\t" liste7[i]
}
}
Match et fonctions
# initialisation variables
BEGIN {
FS=","
ligne=0
}
# recherche de la ligne 901 à 910
FNR > 900 && FNR <= 910 {
print FNR " " $0 "\n$4 : " $4
# recherche et remplace toutes les occurrences de "bg" dans le champ 4
gsub("bg", "#", $4)
# utilisation du \ (\t : tab, \n : retour chariot, ...)
print "gsub(\"bg\", \"#\", $4) : " $4 ; ligne++
}
# retourne le nombre de lignes matchées
END {
print "lignes matchées : " ligne
}
Un autre ?
# fichier awk_wiki.csv
# recherche de la ligne 901 à 909
FNR > 900 && FNR < 910 {
print $3
ligne++
}
# champ 3 commence par G et champ 2 ne se terminant pas par A à L
$3 ~ /^G/ && $2 !~ /[A-L]$/ {
print $2 " " $3
ligne++
}
# retourne le nombre de lignes matchées
END {
print "lignes matchées : " ligne
}
Un dernier juste pour la syntaxe
# manipulation d'une liste
# itération
# commande system
# variables awk : FILENAME, ARGV
# awk -f fichier.awk fichier1.csv fichier2.csv
BEGIN {
FS = ","
# just for fun :)
for (i in ARGV) {
print ARGV[i]
print i }
}
(FILENAME == "fichier1.csv") {
system("test -d /chemin/" $2 "> /tmp/test1")
getline test1 < "/tmp/test1"
system("rm /tmp/test1")
if (test1 == 0) {
lstLogin[$1] = "/chemin/" $2 }
system("test -d /chemin/" $1 "> /tmp/test2")
getline test2 < "/tmp/test2"
system("rm /tmp/test2")
if (test2 == 0) {
lstLogin[$1] = "/chemin/" $1 }
}
(FILENAME == "fichier2.csv") {
for (i in lstLogin) {
if ($1 == i) {
print lstLogin[i] " /chemin2/" $3 "/" $1 } }
}
Liens externes
- la documentation en ligne de sed
- La documentation de gawk
- Je vous invite à visiter le très bon site d'Isabelle Vollant.
- Un lien complet pour les expressions régulières, sed et awk : softndesign
- Encore un petit lien pour sed ici